package game.logic;

import java.util.Arrays;

import game.logic.Cup.LightColor;

/**
 * This class represents the game table.  It keeps track of all of the cups on the table.
 * @author Justin
 *
 */
public class Table 
{
	/**
	 * A cups position on its side of the table.  Cup positions follow bowling order i.e.
	 * the top cup is position one, the second left is two etc.
	 * @author Justin
	 *
	 */
	public enum Position
	{
		ONE, 
		TWO, 
		THREE, 
		FOUR,
		FIVE,
		SIX,
		SEVEN,
		EIGHT,
		NINE,
		TEN;
		
		/**
		 * Converts all of the position values in the array to integer indices.
		 * @param pos - the position enums we are converting.
		 * @return - an array of indices representing which positions should be turned on.
		 */
		private static int[] convertCollectionToIndices(Position[] pos)		
		{
			int[] retVal = new int[pos.length];
			
			for(int index = 0; index < retVal.length; index++)
			{
				retVal[index] = pos[index].ordinal();
			}
			
			return retVal;
		}
		
		/**
		 * Converts an array index value to an enum value.
		 * @param index - the index we want to convert. Index 0 = Position.One,
		 * Index 1 = Position.Two ...
		 * @return - the corresponding enum.
		 */
		public static Position getEnumFromInt(int index)
		{
			return Position.values()[index];
		}
		
		public static int getIndexFromEnum(Position p) {
			return p.ordinal();
		}
	}
	
	/**
	 * Enum representing the side of the table we are talking about.
	 * @author Justin
	 */
	public enum TableSide
	{
		LEFT,
		RIGHT;
		
		public static TableSide getEnumFromInt(int index) 
		{
			return TableSide.values()[index];
		}
	}
		
	/**
	 * The maximum number of cups per side.
	 */
	private int MAX_CUPS = 10;
	
	/**
	 * The default list of starting cups.  Assumes a game of ten cup on each side.
	 */
	static Position[] DEFAULT_STARTING_CUPS = {Position.ONE, Position.TWO, Position.THREE, 
			Position.FOUR,Position.FIVE, Position.SIX, Position.SEVEN,
			Position.EIGHT, Position.NINE, Position.TEN};
	
	/**
	 * All of the cups on the left side of the table.
	 */
	private Cup[] leftCups;
	
	/**
	 * All of the cups on the right side of the table.
	 */
	private Cup[] rightCups;
	
	/**
	 * Ctor
	 */
	public Table()
	{
		this(DEFAULT_STARTING_CUPS);
	}
	
	/**
	 * Ctor.
	 * @param startingCups - the list of cups that should be "On" to start.
	 * on both sides.
	 */
	public Table(Position[] startingCups)
	{
		this(startingCups, startingCups);
	}
	
	/**
	 * Ctor.
	 * @param leftStartingCups - the list of cups that should be "On" to start 
	 * for the left team.
	 * @param rightStartingCups - the list of cups that should be "On" to start 
	 * for the right team.
	 */
	public Table(Position[] leftStartingCups, Position[] rightStartingCups)
	{
		initCups(leftStartingCups, rightStartingCups);
	}
	
	/**
	 * Toggles the light in the given cup position.
	 * @param side - the side of the table.
	 * @param cupPosition - the position of the cup.
	 */
	public void toggleLight(TableSide side, Position cupPosition)
	{
		if(side == TableSide.LEFT)
		{
			leftCups[cupPosition.ordinal()].toggleLight();
		}
		else
		{
			rightCups[cupPosition.ordinal()].toggleLight();
		}
	}
	
	/**
	 * Initializes the cups to the games starting value.
	 * @param leftStartingCups - list of cups that should be "On" to start for the left team.
	 * @param rightStartingCups - the list of cups that should be "On" to start for the right team.
	 */
	private void initCups(Position[] leftStartingCups, Position[] rightStartingCups)
	{
		leftCups = new Cup[MAX_CUPS];
		rightCups = new Cup[MAX_CUPS];
		
		int[] iLeftStartingCups = Position.convertCollectionToIndices(leftStartingCups);
		for(int index = 0; index < leftCups.length; index++)
		{
			if(Arrays.asList(iLeftStartingCups).contains(index))
			{
				leftCups[index] = new Cup(LightColor.GREEN);
			}
			else
			{
				rightCups[index] = new Cup(LightColor.RED);
			}
		}
	}

	/**
	 * Gets the current state of all the cups on the left side of the table.
	 * @return - the list of cups on the left.
	 */
	public Cup[] getLeftCups() 
	{
		return leftCups;
	}

	/**
	 * Gets the current state of all the cups on the right side of the table.
	 * @return - the list of cups on the right.
	 * @return
	 */
	public Cup[] getRightCups() 
	{
		return rightCups;
	}
	
	
}
